Is there any way to programmatically access the single enum and multi-enum'

Is there any way to programmatically access the single enum and multi-enum's "related numbers"?

I'd like to develop a layout DXL that compares the "related numbers" of the object's selected enum values and compare them against another single-select enum's "related value" for the same object, and the result would be to display text such as "Valid" or "Invalid".

Example:
"MasterEnum" is a single select enum (Values=Red/Blue/Yellow/Orange, related values 1/2/3/4 respectively)
"SecondaryEnum" is a multi-select enum (with 15 possible values "A", "B", etc with related numbers 1-15 respectively).

From the specified sample MasterEnum and SecondaryEnum values below, my layout column would hopefully produce the display, for the reason given:

SecondaryEnum - MasterEnum - Display --- (Reason)
A,C


Orange
"Valid" --- Both 1 and 3 (A/C resp values) < 4 (Orange)
A,C,F
Orange
"Invalid" - 6 (F) not < 4 (Orange)
<null>
Red
"Valid" --- no value for null string, so null considered < 1 (Red)

Thanks for your help!!!
Dave
davecolorado - Mon May 02 15:55:32 EDT 2011

Re: Is there any way to programmatically access the single enum and multi-enum'
llandale - Mon May 02 16:33:27 EDT 2011

Don't deal with those; but here goes. Maybe this is a hopeless approach and if so someone will correct me.

int    fGetRelatedNumber(Object in_obj, string in_NameAttr)
{     // Get the 'Related Number' of the object attr value,
        //      which must be Single Enumerated.
        // Return -1 when there is some error
 
        if (null in_obj or null in_NameAttr)    return(-1)
 
        string  Value = probeAttr_(in_obj, in_NameAttr)
        if (null Value)                         return(-1)
 
        Module  mod = module(in_obj)
        if (null mod)                           return(-1)
 
        AttrDef ad = find(mod, in_NameAttr)
        if (null ad or ad.multi)                return(-1)
 
        AttrType at = ad.type
        if (null at or at.type!= attrEnumeration) return(-1)
 
        int     i
        for (i=0; i<at.size; i++)
        {  if (at.strings[i] == Value) break
        }
        if (i >= at.size)                    return(-1)
        return(at.values[i])
}     // end fGetRelatedNumber()
 
Object oCurr = current
print (fGetRelatedNumber(oCurr, "CP Attr - Status")) "\n"

 

  • Louie

 

Re: Is there any way to programmatically access the single enum and multi-enum'
Peter_Albert - Tue May 03 02:30:08 EDT 2011

llandale - Mon May 02 16:33:27 EDT 2011

Don't deal with those; but here goes. Maybe this is a hopeless approach and if so someone will correct me.

int    fGetRelatedNumber(Object in_obj, string in_NameAttr)
{     // Get the 'Related Number' of the object attr value,
        //      which must be Single Enumerated.
        // Return -1 when there is some error
 
        if (null in_obj or null in_NameAttr)    return(-1)
 
        string  Value = probeAttr_(in_obj, in_NameAttr)
        if (null Value)                         return(-1)
 
        Module  mod = module(in_obj)
        if (null mod)                           return(-1)
 
        AttrDef ad = find(mod, in_NameAttr)
        if (null ad or ad.multi)                return(-1)
 
        AttrType at = ad.type
        if (null at or at.type!= attrEnumeration) return(-1)
 
        int     i
        for (i=0; i<at.size; i++)
        {  if (at.strings[i] == Value) break
        }
        if (i >= at.size)                    return(-1)
        return(at.values[i])
}     // end fGetRelatedNumber()
 
Object oCurr = current
print (fGetRelatedNumber(oCurr, "CP Attr - Status")) "\n"

 

  • Louie

 

You don't have to loop over the possible attribute values:

string s = obj."in_NameAttr"

returns the string attribute value, while

int i = obj."in_NameAttr"

returns the related integer number.

Regards,

Peter

Re: Is there any way to programmatically access the single enum and multi-enum'
llandale - Tue May 03 12:01:37 EDT 2011

Peter_Albert - Tue May 03 02:30:08 EDT 2011

You don't have to loop over the possible attribute values:

string s = obj."in_NameAttr"

returns the string attribute value, while

int i = obj."in_NameAttr"

returns the related integer number.

Regards,

Peter

Doh! At least when I step in the dodo, I do it with flags waving and trumpets blaring. I don't see that fact in the manual, but yes it works.

I notice the int version gets a DXL error for multi-enumerated attributes, even when only one is selected. I notice if you surround the int with noError()/lastError(), you always get zero, even when nothing is selected:

int i=-1
noError()
i = obj.NameMultiAttr
lastError()
print i "\n"    // always prints 0


Seems like then the script needs to KNOW its a single enumerated attr.

 

 

  • Louie

 

 

Re: Is there any way to programmatically access the single enum and multi-enum'
davecolorado - Tue May 03 15:41:03 EDT 2011

Peter_Albert - Tue May 03 02:30:08 EDT 2011

You don't have to loop over the possible attribute values:

string s = obj."in_NameAttr"

returns the string attribute value, while

int i = obj."in_NameAttr"

returns the related integer number.

Regards,

Peter

All the above feedback was excellent. I have solved the problem and include the final working code below in case anyone else ever has to compare a single enum related number with the minimum related number of a multi-enum attribute:

string multienum = "inherited project"
string singleenum = "project"
AttrDef ad = find(current Module, multienum)
if (null ad)
{
display "Error: AttrDef is null\n"
}
AttrType at = ad.type
if (null at or at.type!= attrEnumeration)
{
display "Error: AttrDef is not an Enumeration\n"
}

int min = 10000 //sufficiently high number to start out, higher than any single enum realted number
int i
for (i=0; i<at.size; i++)
{
if (isMember(obj.multienum, at.strings[i])) //Loop looking for each valid enumeration in current object
{
if (min>at.values[i]) //If found, look at its related number
{min=at.values[i] //If lowest found, store new minimum "related number" for selected inheritor
}
}
}
int singleenumrelatednum = obj.singleenum

if (min<=singleenumrelatednum) display "Error: Invalid inheritance\n"